package cn.com.dycc.aop;

import java.lang.reflect.Method;
import java.util.Date;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import cn.com.dycc.common.log.SystemServiceLog;
import cn.com.dycc.sys_manage.logsysmanagement.dao.OperateLogDao;
import cn.com.dycc.sys_manage.logsysmanagement.entity.OperateLog;
import cn.com.dycc.util.DateUtil;
import cn.com.dycc.util.Log;
import cn.com.dycc.util.LogUtil;
import cn.com.dycc.util.SessionInfo;

/**
 * 切面组件，用于记录日志功能
 * 
 * @author Liket
 *
 */


@Component
@Aspect
//@SuppressWarnings("rawtypes")
public class LogAspect {
	
	/**
	 * 日志记录
	 */
	private static final Logger LOGGER = Logger.getLogger(LogAspect.class);

	/**
	 * 自定义类切点
	 * @throws Throwable 
	 */	
	@Pointcut("@annotation(cn.com.dycc.common.log.SystemServiceLog)")	
	public void serviceAspect() {		
		
	}
	@Around("serviceAspect()")
	public Object doServiceLog(ProceedingJoinPoint jp) throws Throwable {		
		LOGGER.info("日志记录");
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
				.getRequest();
		//获取方法名
		Signature sign = jp.getSignature();
		String method_name = sign.toString();
		method_name = method_name.substring(method_name.lastIndexOf(".")+1, method_name.indexOf("("));
		//System.out.println(method_name);
		
		
		SessionInfo info = null;
		OperateLog log = new OperateLog();
		String operate = "";		
		try {
			if("exit".equals(method_name)){
				info = new SessionInfo(request);				
			}
			//log.setOperationType(getServiceMthodTableType(joinPoint));
			// 获取日志描述信息
			operate = getServiceMthodDescription(jp);			
			log.setResult("成功");			
			//log.setRemarks(getServiceMthodParams(joinPoint));			
			return jp.proceed();
		} catch (RuntimeException e) {
			log.setResult("失败");
			LOGGER.error("异常信息:{}", e);
			throw e;
		} catch (Exception e2) {
			log.setResult("失败");
			LOGGER.error("异常信息:{}", e2);
			throw e2;
		}finally{
			if(info==null){
				// 获取session记录的信息
				info = new SessionInfo(request);
			}			
			if("login".equals(method_name)){
				Object agrs[] = jp.getArgs();
				String account = agrs[0].toString();
				//System.out.println("account="+account);
				log.setAccount(account);
			}else{
				log.setAccount(info.getAccount());
			}
			// 数据库日志
			log.setUser_id(info.getUser_id());
			//log.setAccount(info.getAccount());
			log.setUsername(info.getUsername());
			log.setIp(info.getIp());
			
			log.setCreate_date(new Date());
			log.setLogin_date(new Date());			
			
			log.setOperate(operate);			
			log.setOrg_id("1");
//			System.out.println("log="+log.toString());
			Log.addLog(log);		
			
		}
		
		
	}
	
	/** 
     * getServiceMthodParams:获取json格式的参数. <br/> 
     * @author lcma 
     * @param joinPoint 
     * @return 
     * @throws Exception 
     * @since JDK 1.7 
     */  
    /*private String getServiceMthodParams(JoinPoint joinPoint)  
            throws Exception {  
       Object[] arguments = joinPoint.getArgs();  
       String params = JacksonUtil.toJSon(arguments);  
       return params;  
   }*/  
	
	/** 
     * getServiceMthodTableType:获取注解中对方法的数据表类型 用于service层注解 . <br/> 
     * @author lcma 
     * @param joinPoint 
     * @return 
     * @throws Exception 
     * @since JDK 1.7 
     */  
    private int getServiceMthodTableType(JoinPoint joinPoint)  
            throws Exception {  
       String targetName = joinPoint.getTarget().getClass().getName();  
       String methodName = joinPoint.getSignature().getName();  
       Object[] arguments = joinPoint.getArgs();  
       Class targetClass = Class.forName(targetName);  
       Method[] methods = targetClass.getMethods();  
       int tableType = 0;  
        for (Method method : methods) {  
            if (method.getName().equals(methodName)) {  
               Class[] clazzs = method.getParameterTypes();  
                if (clazzs.length == arguments.length) {  
                tableType = method.getAnnotation(SystemServiceLog.class).tableType();  
                    break;  
               }  
           }  
       }  
        return tableType;  
   }
    
	 /** 
     * getServiceMthodDescription:获取注解中对方法的描述信息 用于service层注解  . <br/> 
     * @author lcma 
     * @param joinPoint 切点  
     * @return 方法描述 
     * @throws Exception  
     * @since JDK 1.7 
     */  
    private String getServiceMthodDescription(JoinPoint joinPoint)  
               throws Exception {  
          String targetName = joinPoint.getTarget().getClass().getName();  
          String methodName = joinPoint.getSignature().getName();  
          Object[] arguments = joinPoint.getArgs();  
          Class targetClass = Class.forName(targetName);  
          Method[] methods = targetClass.getMethods();  
          String description = "";  
           for(Method method : methods) {  
               if(method.getName().equals(methodName)) {  
                  Class[] clazzs = method.getParameterTypes();  
                   if(clazzs.length == arguments.length) {  
                      description = method.getAnnotation(SystemServiceLog.class).description();  
                       break;  
                  }  
              }  
          }  
          return description;  
      }

}
